Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(erc1155): add custom ERC1155 contract for airdrop #262

Merged
merged 6 commits into from
Mar 21, 2023
Merged

Conversation

dohaki
Copy link
Contributor

@dohaki dohaki commented Mar 20, 2023

Part of ACX-950

I also deployed to Mumbai Testnet here https://mumbai.polygonscan.com/address/0x17496824ba574a4e9de80110a91207c4c63e552a and tested the integration with OpenSea here https://testnets.opensea.io/assets/mumbai/0x17496824ba574a4e9de80110a91207c4c63e552a/0.

But I wasn't able to verify the contract via Polyscan though 🤔 When I run

yarn hardhat etherscan-verify --network polygon-mumbai --license AGPL-3.0 --force-license --solc-input

with the env var POLYGON_ETHERSCAN_API_KEY being set, I get

verifying MintableERC1155 (0x17496824Ba574A4e9De80110A91207c4c63e552a) ...
contract MintableERC1155 failed to submit : "NOTOK" : "Invalid API Key" [object Object]
already verified: PolygonTokenBridger (0x97f102f2f73717e203f964Ad9940e4C2e79b8597), skipping.
already verified: Polygon_SpokePool (0x45fF03629D024b7763275e732a2d80202c18b31C), skipping.

Copy link
Member

@nicholaspai nicholaspai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is awesome @dohaki and the scripts + tests look great. My main recommendation is to remove the AccessControlEnumerable and just replace it with a simple Ownable. We can have the owner have minting, pausing, and setting URI ability. This will keep the contract simpler.

My other suggestion is to add NatSpec comments to all Solidity files. This will importantly render the function comments and descriptions on Etherscan! GitHub CoPilo is great for this ;)

Copy link
Contributor

@james-a-morris james-a-morris left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a few comments. Looks amazing so far, @dohaki

contracts/erc1155/MintableERC1155.sol Outdated Show resolved Hide resolved
contracts/erc1155/MintableERC1155.sol Outdated Show resolved Hide resolved
contracts/erc1155/MintableERC1155.sol Outdated Show resolved Hide resolved
contracts/erc1155/MintableERC1155.sol Outdated Show resolved Hide resolved
Comment on lines 42 to 44
function setTokenURI(uint256 tokenId, string memory tokenURI) external onlyOwner {
_tokenURIs[tokenId] = tokenURI;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want it to be possible to reset a token URI after it's already been set?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm I guess not actually, it would give holders more confidence. So maybe require existing tokenURI is empty

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a require here 898de67

* @param tokenId Token type to airdrop.
* @param amount Amount of token types to airdrop.
*
* NOTE: Call might run out of gas if `recipients` arg too long. Might need to chunk up the list.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would just make this a @dev call instead of NOTE

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done 898de67

constructor() ERC1155("") {}

/**
* @dev Creates `amount` new tokens for `recipients` of token type `tokenId`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit, explanation of function should be @notice not @dev. Use @dev for caller warnings like the out of gas limit

* @param tokenURI URI of token metadata.
*/
function setTokenURI(uint256 tokenId, string memory tokenURI) external onlyOwner {
_tokenURIs[tokenId] = tokenURI;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: emit an Event after changing state. Something like SetTokenURI(uint256 tokenId, string newUri)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes good point. Actually in the spec we should emit URI(uri, tokenId). See https://eips.ethereum.org/EIPS/eip-1155#specification

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perfect!

* `setTokenURI` to allow IPFS URIs for all token types.
* @param tokenId Token type to retrieve metadata URI for.
*/
function uri(uint256 tokenId) public view virtual override returns (string memory) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: no need to make this virtual anymore

}

/**
* @dev Instead of returning the same URI for *all* token types, we return the uri set by
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Add a @notice explaining this function. Can use @inheritdoc ERC1155 for example

}

/**
* @dev Sets the URI for token of type `tokenId` to `tokenURI`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: make @notice

Copy link
Member

@nicholaspai nicholaspai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! I left some nits

dohaki added 3 commits March 20, 2023 17:04
- emit URI event
- require token uri not set
- doc improvements
@dohaki dohaki requested a review from mrice32 March 20, 2023 16:11
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";

contract MintableERC1155 is ERC1155, Ownable {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: add a @title, @notice comment above the Contract. Something like:

@title MintableERC1155
@notice Ownable contract enabling owner to airdrop many recipients the same token ID at once

import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";

contract MintableERC1155 is ERC1155, Ownable {
mapping(uint256 => string) public _tokenURIs;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should add comment above all state vars including _tokenURIs

event Airdrop(address caller, uint256 tokenId, address[] recipients, uint256 amount);

// solhint-disable-next-line
constructor() ERC1155("") {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might add a comment why you're passing in "" (because we opt to use the _tokenURIs mapping instead)

airdropTx.hash
);
await airdropTx.wait();
console.log(`Successfully minted token to:`, recipientsChunk);
Copy link
Contributor

@amateima amateima Mar 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would make sense to set the token URI here too or we'll submit a manual tx for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to create a separate script in a separate PR that does this. Basically

  • Parse and validate metadata
  • Upload to IPFS
  • Set token URI

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔥

Copy link
Contributor

@mrice32 mrice32 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@dohaki dohaki merged commit 7acc87e into master Mar 21, 2023
@dohaki dohaki deleted the erc1155 branch March 21, 2023 08:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants